/**
 * 实现一个LazyMan，可以按照以下方式调用:
    LazyMan(“Hank”)输出:
    Hi! This is Hank!
     
    LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
    Hi! This is Hank!
    //等待10秒..
    Wake up after 10
    Eat dinner~
     
    LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出
    Hi This is Hank!
    Eat dinner~
    Eat supper~
     
    LazyMan(“Hank”).sleepFirst(5).eat(“supper”)输出
    //等待5秒
    Wake up after 5
    Hi This is Hank!
    Eat supper
     
    以此类推。
 * 
 */


function LazyMan(name) {
    this.name = name;
    this.fnsList = [];

    this.next = function () {
        let fn = this.fnsList.shift();
        fn && fn();
    }

    // 尾调用
    setTimeout(() => {
        this.next();
    }, 0)

    return this.constructor === LazyMan ? this : new LazyMan(name);
}

LazyMan.prototype.eat = function (food) {
    // console.log(this)
    const self = this;
    this.fnsList.push(() => {
        (function () {
            console.log(`Eat ${food}`);
            self.next();
        })()
    })
    return this;
}

LazyMan.prototype.sleepFirst = function (duration) {
    const self = this;
    this.fnsList.unshift(() => {
        (function () {
            setTimeout(() => {
                console.log(`Sleep Before ${duration}`);
                self.next();
            }, duration)
        })()
    });
    return this;
}


LazyMan.prototype.sleep = function (duration) {
    const self = this;
    this.fnsList.push(() => {
        (function () {
            setTimeout(() => {
                console.log(`Sleep After ${duration}`);
                self.next();
            }, duration)
        })()
    })
    return this;
}

LazyMan('liao').eat('bread').eat('milk').sleep(3000).eat('haha').sleepFirst(2000);